<template>
  <div id="container" />
</template>
<script setup lang="ts">
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
import { onMounted } from 'vue'
let camera: THREE.Camera;
let scene: THREE.Scene;
let renderer: THREE.WebGLRenderer;
let orbitControls: any;
let clock: any;
let composer: any;
let unrealBloomPass: any;

function init() {
  createScene() // 创建场景
  createModels() // 创建模型
  createLight() // 创建光源
  createCamera() // 创建相机
  createRender() // 创建渲染器
  createControls() // 创建控件对象
  createComposer()
  render() // 渲染
}
// 创建场景
function createScene() {
  scene = new THREE.Scene()
}
// function createCube() {
//   const cubeSize = Math.ceil(Math.random() * 3)
//   const cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize)
//   const material = new THREE.MeshLambertMaterial({
//     color: Math.random() * 0xffffff
//   })
//   const cube = new THREE.Mesh(cubeGeometry, material)

//   // 给方块设置随机坐标
//   cube.position.x = -30 + Math.round(Math.random() * 60)
//   cube.position.y = Math.round(Math.random() * 5)
//   cube.position.z = -20 + Math.round(Math.random() * 40)
//   // 将生成的方块添加到场景
//   scene.add(cube)
// }
// function createSphere() {
//   const sphereSize = Math.ceil(Math.random() * 1)
//   const sphereGeometry = new THREE.SphereGeometry(sphereSize, 50, 50)
//   const material = new THREE.MeshLambertMaterial({
//     color: Math.random() * 0xffffff
//   })
//   const mesh = new THREE.Mesh(sphereGeometry, material)

//   // 设置随机坐标
//   mesh.position.x = -30 + Math.round(Math.random() * 60)
//   mesh.position.y = Math.round(Math.random() * 5)
//   mesh.position.z = -20 + Math.round(Math.random() * 40)
//   // 将生成的球添加到场景
//   scene.add(mesh)
// }
function LoadModel(obj: any, mtl: any) {
  var objloader = new OBJLoader();//obj加载器
  var mtlloader = new MTLLoader();//材质文件加载器
  mtlloader.load(mtl, function (materials) {
    // 返回一个包含材质的对象MaterialCreator
    console.log(materials);
    //obj的模型会和MaterialCreator包含的材质对应起来
    objloader.setMaterials(materials);
    objloader.load(obj, function (obj) {
      console.log(obj, 'obj.attributes');
      obj.position.set(0, 13, 0);
      // obj.translateY(1.5);
      scene.add(obj);//返回的组对象插入场景中
      // obj.children[0].scale.set(135, 135, 135);//网格模型缩放
      // obj.children[0].scale.set(0.5, 0.5, 5);
      window.meshObj = obj;
    })
  })

}
// 创建模型
function createModels() {
  // for (let i = 0; i < 10; i++) {
    // createCube()
    // createSphere()
    LoadModel('/obj/model.obj', '/obj/material.mtl');
  // }
}

// 创建光源
function createLight() {
  // 环境光
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.3) // 创建环境光
  scene.add(ambientLight) // 将环境光添加到场景

  const directionLight = new THREE.DirectionalLight(0xffffff)
  directionLight.position.set(550, 100, 550)
  directionLight.intensity = 0.8
  scene.add(directionLight)
}
// 创建相机
function createCamera() {
  const element = document.getElementById('container')
  const width = element.clientWidth // 窗口宽度
  const height = element.clientHeight // 窗口高度
  const k = width / height // 窗口宽高比
  // PerspectiveCamera( fov, aspect, near, far )
  camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)
  camera.position.set(30, 30, 30) // 设置相机位置

  camera.lookAt(new THREE.Vector3(0, 0, 0)) // 设置相机方向
}
// 创建渲染器
function createRender() {
  const element = document.getElementById('container')
  renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
  renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
  renderer.shadowMap.enabled = true // 显示阴影
  renderer.setClearColor(0x000000, 1) // 设置背景颜色
  element.appendChild(renderer.domElement)
}

function createComposer() {
  //使用场景和相机创建RenderPass通道
  const renderPass = new RenderPass(scene, camera)

  //创建UnrealBloomPass泛光通道
  unrealBloomPass = new UnrealBloomPass(
    new THREE.Vector2(256, 256),
    1,
    1.1,
    0.18
  )
  unrealBloomPass.renderToScreen = true

  //创建效果组合器
  composer = new EffectComposer(renderer)

  //将创建的通道添加到EffectComposer(效果组合器)对象中
  composer.addPass(renderPass)
  composer.addPass(unrealBloomPass)
}

function render() {
  const delta = clock.getDelta() // 获取自上次调用的时间差
  orbitControls.update(delta) // 相机控制更新

  renderer.render(scene, camera)

  /********** 更新效果组合器一定要在渲染器更新后，否则通道无法产生效果************/
  composer.render(delta) //效果组合器更新

  requestAnimationFrame(render)
}
// 创建控件对象
function createControls() {
  clock = new THREE.Clock() // 创建THREE.Clock对象，用于计算上次调用经过的时间
  orbitControls = new OrbitControls(
    camera,
    renderer.domElement
  )
}
onMounted(() => {
  init();
})

</script>
  
<style>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
}
</style>
  
  